package com.me.service;

import com.me.annotation.Inject;
import com.me.dao.DbContext;
import com.me.dao.db.DbSet;
import com.me.dao.db.KeyValuePairs;
import com.me.enums.OrderStatus;
import com.me.model.Goods;
import com.me.model.Order;
import com.me.model.Orderitem;
import com.me.model.User;

import java.math.BigDecimal;
import java.util.Collection;

public class OrderService {
	private DbSet<Goods> gdao;
	private DbSet<Order> odao;
	private DbSet<Orderitem> oidao;

	@Inject
	public OrderService(DbContext ctx) {
		gdao = ctx.getGoods();
		odao = ctx.getOrders();
		oidao = ctx.getOrderItems();
	}

	public Collection<Orderitem> getUserCart(User u) {
		Order o = getUnCommitOrder(u.getId());

		Collection<Orderitem> ois = oidao.findAll("orderid", o.getId());

		for (Orderitem oi : ois) {
			oi.setGoods(gdao.find("id", oi.getGoodsid()));
		}

		return ois;
	}

	public boolean addToOrder(User u, String goodsId) {
		Order o;
		Goods g;
		Orderitem oi;

		o = getUnCommitOrder(u.getId());

		g = gdao.find("id", goodsId);

		if (!oidao.existAll(new KeyValuePairs().add("goodsid", goodsId).add("orderid",o.getId()))) {
			oi = new Orderitem(g, o.getId());
			oidao.add(oi);
		} else {
			oi = oidao.find(new KeyValuePairs().add("goodsid", goodsId).add("orderid",o.getId()));
		}

		o.setAmount(o.getAmount() + 1);
		oi.increse();

		oidao.update(oi, "id", oi.getId());

		o.setTotal(o.getDTotal().add(g.getDPrice()));
		odao.update(o, "id", o.getId());

		odao.save();
		oidao.save();

		return true;
	}

	public boolean reduceFromCart(User u, String goodsid) {
		Order o = getUnCommitOrder(u.getId());
		Goods g = gdao.find("id", goodsid);
		Orderitem oi = oidao.find(new KeyValuePairs().add("goodsid", goodsid).add("orderid",o.getId()));

		if (!oi.reduce()) {
			return deleteFromCart(u, goodsid);
		}
		oidao.update(oi, "id", oi.getId());

		o.setAmount(o.getAmount() - 1);
		o.setTotal(o.getDTotal().subtract(g.getDPrice()));
		odao.update(o, "id", o.getId());

		odao.save();
		oidao.save();
		return true;
	}

	public boolean deleteFromCart(User u, String goodsid) {
		Order o = getUnCommitOrder(u.getId());
		Goods g = gdao.find("id", goodsid);
		Orderitem oi = oidao.find(new KeyValuePairs().add("goodsid", goodsid).add("orderid",o.getId()));
		oidao.remove(oi);

		o.setAmount(o.getAmount() - oi.getAmount());

		o.setTotal(o.getDTotal().subtract(g.getDPrice().multiply(BigDecimal.valueOf(oi.getAmount()))));
		odao.update(o, "id", o.getId());

		odao.save();
		oidao.save();
		return true;
	}


	public int getCartNum(User u) {
		Order o = getUnCommitOrder(u.getId());
		return o.getAmount();
	}

	public Order getUnCommitOrder(String id) {
		return odao.find(new KeyValuePairs().add("userid", id).add("status", OrderStatus.uncommit));
	}

	public void checkCartExist(User u) {
		if (!odao.existAll(new KeyValuePairs().add("userid", u.getId()).add("status", OrderStatus.uncommit))) {
			Order o = new Order(u);
			odao.add(o);
			odao.save();
		}

	}

	public void PreparePay(User u,Order o) {
		o.setStatus(OrderStatus.unpay);
		odao.update(o, "id", o.getId());
		odao.save();
		checkCartExist(u);
	}

	public void setSuccessPay(String oid) {
		Order o = odao.find("id",oid);
		o.refreshTime();
		o.setStatus(OrderStatus.pay);
		o.setPayType(2);

		odao.update(o, "id", o.getId());
		odao.save();
	}

	public Collection<Order> getOrders(User u) {
		Collection<Order> os = odao.findAll("userid",u.getId());

		for (Order o : os) {
			Collection<Orderitem> ois = oidao.findAll("orderid", o.getId());
			o.setOis(ois);

			for (Orderitem oi : ois) {
				oi.setGoods(gdao.find("id",oi.getGoodsid()));
			}
		}

		return os;
	}
}
